package sdu.icat.pj.service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.transaction.Transactional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import sdu.icat.pj.repository.SysMenuRepository;
import sdu.icat.pj.repository.SysRoleMenuRepository;
import sdu.icat.pj.repository.SysUserMenuRepository;
import sdu.icat.pj.repository.SysUserRoleRepository;
import sdu.icat.pj.support.Constants;
import sdu.icat.pj.util.InstanceUtil;
import sdu.icat.sys.smodel.SysMenu;
import sdu.icat.sys.smodel.SysRoleMenu;
import sdu.icat.sys.smodel.SysUserMenu;
import sdu.icat.sys.smodel.SysUserRole;

/**
 * 系统权限
 * @author ljh_2015
 *
 */
@Service
@CacheConfig(cacheNames="sysAuthorize")
public class SysAuthorizeService {

    @Autowired
    private SysUserMenuRepository sysUserMenuMapper;
    @Autowired
    private SysUserRoleRepository sysUserRoleMapper;
    @Autowired
    private SysRoleMenuRepository sysRoleMenuMapper;
    
    @Autowired 
    private SysMenuRepository sysMenuRepository;

    public List<String> queryMenuIdsByUserId(Long userId) {
	List<String> resultList = InstanceUtil.newArrayList();
	List<SysUserMenu> list = sysUserMenuMapper.findByUserId(userId);
	for (SysUserMenu menu : list) {
	    resultList.add(menu.getMenuId().toString());
	}
	return resultList;
    }

    @Transactional
    @CacheEvict(value = { Constants.CACHE_NAMESPACE + "menuPermission", Constants.CACHE_NAMESPACE + "sysPermission",
	    Constants.CACHE_NAMESPACE + "userPermission" }, allEntries = true)
    public void updateUserMenu(List<SysUserMenu> sysUserMenus) {
	Long userId = null;
	for (SysUserMenu sysUserMenu : sysUserMenus) {
	    if (sysUserMenu != null && sysUserMenu.getUserId() != null && "read".equals(sysUserMenu.getPermission())) {
		userId = sysUserMenu.getUserId();
	    }
	}
	if (userId != null) {
	    SysUserMenu s = sysUserMenuMapper.findByUserIdAndPermission(userId, "read");
	    sysUserMenuMapper.delete(s);
	}
	for (SysUserMenu sysUserMenu : sysUserMenus) {
	    if (sysUserMenu != null && sysUserMenu.getUserId() != null && sysUserMenu.getMenuId() != null
		    && "read".equals(sysUserMenu.getPermission())) {
		sysUserMenuMapper.save(sysUserMenu);
	    }
	}
    }

//    @Transactional
//    @CacheEvict(value = { Constants.CACHE_NAMESPACE + "menuPermission", Constants.CACHE_NAMESPACE + "sysPermission",
//	    Constants.CACHE_NAMESPACE + "userPermission" }, allEntries = true)
//    public void updateUserPermission(List<SysUserMenu> sysUserMenus) {
//	Long userId = null;
//	for (SysUserMenu sysUserMenu : sysUserMenus) {
//	    if (sysUserMenu != null && sysUserMenu.getUserId() != null) {
//		userId = sysUserMenu.getUserId();
//		break;
//	    }
//	}
//	if (userId != null) {
//	    Map<String, Object> dicParam = InstanceUtil.newHashMap();
//	    dicParam.put("type", "CRUD");
//	    List<SysDic> sysDics = sysDicService.queryList(dicParam);
//	    for (SysDic sysDic : sysDics) {
//		if (sysDic != null && !"read".equals(sysDic.getCode())) {
//		    sysAuthorizeMapper.deleteUserMenu(userId, sysDic.getCode());
//		}
//	    }
//	}
//	for (SysUserMenu sysUserMenu : sysUserMenus) {
//	    if (sysUserMenu != null && sysUserMenu.getUserId() != null && sysUserMenu.getMenuId() != null
//		    && !"read".equals(sysUserMenu.getPermission())) {
//		sysUserMenuMapper.save(sysUserMenu);
//	    }
//	}
//    }

    public List<SysUserRole> getRolesByUserId(Long userId) {
	List<SysUserRole> userRoles = sysUserRoleMapper.findByUserId(userId);
	return sysUserRoleMapper.findByUserId(userId);
    }

    @Transactional
    @CacheEvict(value = { Constants.CACHE_NAMESPACE + "menuPermission", Constants.CACHE_NAMESPACE + "sysPermission",
	    Constants.CACHE_NAMESPACE + "userPermission",
	    Constants.CACHE_NAMESPACE + "rolePermission" }, allEntries = true)
    public void updateUserRole(List<SysUserRole> sysUserRoles) {
	Long userId = null;
	for (SysUserRole sysUserRole : sysUserRoles) {
	    if (sysUserRole != null && sysUserRole.getUserId() != null) {
		userId = sysUserRole.getUserId();
		break;
	    }
	}
	if (userId != null) {
	    List<SysUserRole> roles = sysUserRoleMapper.findByUserId(userId);
	    for(SysUserRole role:roles) {
		sysUserRoleMapper.delete(role);
	    }
	}
	for (SysUserRole sysUserRole : sysUserRoles) {
	    if (sysUserRole != null && sysUserRole.getUserId() != null && sysUserRole.getRoleId() != null) {
		sysUserRoleMapper.save(sysUserRole);
	    }
	}
    }

    public List<String> queryMenuIdsByRoleId(Long roleId) {
	List<String> resultList = InstanceUtil.newArrayList();
	List<SysRoleMenu> list = sysRoleMenuMapper.findByRoleId(roleId);
	for (SysRoleMenu menu : list) {
	    resultList.add(menu.getMenuId().toString());
	}
	return resultList;
    }

    @Transactional
    @CacheEvict(value = { Constants.CACHE_NAMESPACE + "menuPermission", Constants.CACHE_NAMESPACE + "sysPermission",
	    Constants.CACHE_NAMESPACE + "userPermission",
	    Constants.CACHE_NAMESPACE + "rolePermission" }, allEntries = true)
    public void updateRoleMenu(List<SysRoleMenu> sysRoleMenus) {
	Long roleId = null;
	for (SysRoleMenu sysRoleMenu : sysRoleMenus) {
	    if (sysRoleMenu != null && sysRoleMenu.getRoleId() != null && "read".equals(sysRoleMenu.getPermission())) {
		roleId = sysRoleMenu.getRoleId();
		break;
	    }
	}
	if (roleId != null) {
	    SysRoleMenu rm = sysRoleMenuMapper.findByRoleIdAndPermission(roleId, "read");
	    sysRoleMenuMapper.delete(rm);
	}
	for (SysRoleMenu sysRoleMenu : sysRoleMenus) {
	    if (sysRoleMenu != null && sysRoleMenu.getRoleId() != null && sysRoleMenu.getMenuId() != null
		    && "read".equals(sysRoleMenu.getPermission())) {
		sysRoleMenuMapper.save(sysRoleMenu);
	    }
	}
    }

//    @Transactional
//    @CacheEvict(value = { Constants.CACHE_NAMESPACE + "menuPermission", Constants.CACHE_NAMESPACE + "sysPermission",
//	    Constants.CACHE_NAMESPACE + "userPermission",
//	    Constants.CACHE_NAMESPACE + "rolePermission" }, allEntries = true)
//    public void updateRolePermission(List<SysRoleMenu> sysRoleMenus) {
//	Long roleId = null;
//	for (SysRoleMenu sysRoleMenu : sysRoleMenus) {
//	    if (sysRoleMenu != null && sysRoleMenu.getRoleId() != null) {
//		roleId = sysRoleMenu.getRoleId();
//	    }
//	}
//	if (roleId != null) {
//	    Map<String, Object> dicParam = InstanceUtil.newHashMap();
//	    dicParam.put("type", "CRUD");
//	    List<SysDic> sysDics = sysDicService.queryList(dicParam);
//	    for (SysDic sysDic : sysDics) {
//		if (sysDic != null && !"read".equals(sysDic.getCode())) {
//		    sysAuthorizeMapper.deleteRoleMenu(roleId, sysDic.getCode());
//		}
//	    }
//	}
//	for (SysRoleMenu sysRoleMenu : sysRoleMenus) {
//	    if (sysRoleMenu != null && sysRoleMenu.getRoleId() != null && sysRoleMenu.getMenuId() != null
//		    && !"read".equals(sysRoleMenu.getPermission())) {
//		sysRoleMenuMapper.save(sysRoleMenu);
//	    }
//	}
//    }

//    @Cacheable(value = Constants.CACHE_NAMESPACE + "menuPermission")
//    public List<SysMenu> queryAuthorizeByUserId(Long userId) {
//	List<Long> menuIds = sysAuthorizeMapper.getAuthorize(userId);
//	List<SysMenu> menus = sysMenuService.getList(menuIds);
//	Map<Long, List<SysMenu>> map = InstanceUtil.newHashMap();
//	for (SysMenu sysMenu : menus) {
//	    if (sysMenu != null && map.get(sysMenu.getParentId()) == null) {
//		List<SysMenu> menuBeans = InstanceUtil.newArrayList();
//		map.put(sysMenu.getParentId(), menuBeans);
//	    }
//	    map.get(sysMenu.getParentId()).add(sysMenu);
//	}
//	List<SysMenu> result = InstanceUtil.newArrayList();
//	for (SysMenu sysMenu : menus) {
//	    if (sysMenu != null && sysMenu.getParentId() == null || sysMenu.getParentId() == 0) {
//		sysMenu.setLeaf(0);
//		sysMenu.setMenuBeans(getChildMenu(map, sysMenu.getId()));
//		result.add(sysMenu);
//	    }
//	}
//	return result;
//    }

    // 递归获取子菜单
    private List<SysMenu> getChildMenu(Map<Long, List<SysMenu>> map, Long id) {
	List<SysMenu> menus = map.get(id);
	if (menus != null) {
	    for (SysMenu sysMenu : menus) {
		if (sysMenu != null) {
		    sysMenu.setMenuBeans(getChildMenu(map, sysMenu.getId()));
		}
	    }
	}
	return menus;
    }

    @Cacheable(Constants.CACHE_NAMESPACE + "sysPermission")
    public List<String> queryPermissionByUserId(Long userId) {
	List<String> permissions = InstanceUtil.newArrayList();
	List<SysUserRole> roles = sysUserRoleMapper.findByUserId(userId);
	for(SysUserRole role:roles) {
	    List<SysRoleMenu> roleMenu = sysRoleMenuMapper.findByRoleId(role.getRoleId());
	    for(SysRoleMenu menu:roleMenu) {
		permissions.add(menu.getPermission());
	    }
	}
	return permissions;
    }

    @Cacheable(Constants.CACHE_NAMESPACE + "userPermission")
    public List<String> queryUserPermission(Long userId) {
	List<SysUserMenu> list = sysUserMenuMapper.findByUserId(userId);
	List<String> permissions = new ArrayList<>();
	for(SysUserMenu menu:list) {
	    permissions.add(menu.getPermission());
	}
	return permissions;
    }

    @Cacheable(Constants.CACHE_NAMESPACE + "rolePermission")
    public List<String> queryRolePermission(Long roleId) {
	List<SysRoleMenu> list = sysRoleMenuMapper.findByRoleId(roleId);
	List<String> permissions = new ArrayList<>();
	for(SysRoleMenu menu:list) {
	    permissions.add(menu.getPermission());
	}
	return permissions;
    }

    public List<SysMenu> queryMenusPermission() {
	List<SysRoleMenu> list = sysRoleMenuMapper.findAll();
	List<SysMenu> menus = new ArrayList<>();
	for(SysRoleMenu menu:list) {
	    menus.add(sysMenuRepository.findOne(menu.getMenuId()));
	}
	return menus;
    }

    public Map<String, Object> queryUserPermissions(SysUserMenu sysUserMenu) {
	List<SysUserMenu> list = sysUserMenuMapper.findByUserId(sysUserMenu.getUserId());
	Map<String,Object> permissionsMap = InstanceUtil.newHashMap();
	for(SysUserMenu menu:list) {
	    String menuId = menu.getMenuId().toString();
	    String permission = menu.getPermission();
	    permissionsMap.put(menuId, permission);
	}
	return permissionsMap;
    }

    public Map<String, Object> queryRolePermissions(SysRoleMenu sysRoleMenu) {
	List<SysRoleMenu> list = sysRoleMenuMapper.findByRoleId(sysRoleMenu.getRoleId());
	Map<String,Object> permissionsMap = InstanceUtil.newHashMap();
	for(SysRoleMenu menu:list) {
	    String roleId = menu.getRoleId().toString();
	    String permission = menu.getPermission();
	    permissionsMap.put(roleId, permission);
	}
	return permissionsMap; 
    }

}
